package com.test.ant.payment.handler;

import com.test.ant.payment.service.PaymentRemoteService;
import com.test.ant.payment.util.ConsultResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author ll
 * @Date 2018/1/10 23:54
 */
@Service
public class PaymentTypeEnableHandler extends Thread {
    private static final Logger logger = LoggerFactory.getLogger(PaymentTypeEnableHandler.class);
    /**
     * 默认最长超时时间（可动态配置） 2S
     */
    private static final int INTERRUPT_TIME = 2000;
    /**
     * 默认最大线程数量
     * ((线程等待时间+线程CPU时间 ) / 线程CPU时间 ) * CPU数目
     */
    private static final int DEFAULT_MAX_THREAD = ((1 + 2) * 2) * Runtime.getRuntime().availableProcessors();
    @Autowired
    private PaymentRemoteService paymentRemoteService;//PaymentRemoteSerivce
    public PaymentTypeEnableHandler(PaymentRemoteService paymentRemoteService) {
        this.paymentRemoteService = paymentRemoteService;
    }
    private int cursor;
    private Counter counter;
    private List<String> allPaymentList;
    private List<String> paymentTypeEnableList;

    /**
     * 构造函数
     *
     * @param allPaymentList        支付方式列表
     * @param cursor                支付方式索引
     * @param paymentTypeEnableList 可用支付方式列表
     * @param counter               计数器
     */
    public PaymentTypeEnableHandler(List<String> allPaymentList, int cursor, List<String> paymentTypeEnableList, Counter counter) {
        this.allPaymentList = allPaymentList;
        this.cursor = cursor;
        this.paymentTypeEnableList = paymentTypeEnableList;
        this.counter = counter;
    }

    @Override
    public void run() {
        do {
            String paymentType = allPaymentList.get(this.cursor);
            ConsultResult consultResult = paymentRemoteService.isEnabled(paymentType);
            if (consultResult != null && consultResult.getIsEnable()) {
                paymentTypeEnableList.add(paymentType);
            } else {
                logger.error("PaymentRemoteService isEnabled acquire failure, paymentType:{} | {}", paymentType, consultResult);
            }
            this.cursor = this.counter.getCursorIndex();
        } while (this.cursor != -1);
    }

    public List<String> acquireEnablePayment(List<String> allPaymentList) {
        if (CollectionUtils.isEmpty(allPaymentList)) {
            return paymentTypeEnableList;
        }
        List<String> paymentTypeEnableList = Collections.synchronizedList(new ArrayList<String>());
        List<PaymentTypeEnableHandler> threads = new ArrayList<>();

        try {
            Counter counter = new Counter(allPaymentList.size());
            int cursor = counter.getCursorIndex();
            int threadCount = 0;
            do {
                PaymentTypeEnableHandler paymentTypeEnableHandler =
                        new PaymentTypeEnableHandler(allPaymentList, cursor, paymentTypeEnableList, counter);
                threads.add(paymentTypeEnableHandler);
                paymentTypeEnableHandler.start();
            } while (cursor != -1 && ++threadCount < DEFAULT_MAX_THREAD);

            for (PaymentTypeEnableHandler paymentTypeEnableHandler : threads) {
                try {
                    paymentTypeEnableHandler.join(INTERRUPT_TIME);
                } catch (InterruptedException e) {
                    logger.error("acquireDisablePayment InterruptedException, ThreadName : {}", Thread.currentThread().getName(), e.getMessage(), e);
                }
            }
        } catch (Exception e) {
            logger.error("acquireDisablePayment Exception, ThreadName : {}", Thread.currentThread().getName(), e.getMessage(), e);
        }
        return paymentTypeEnableList;
    }
}
